﻿using System.Collections.Generic;
using System.Linq;

namespace ComeSeeThis_MVC2.Models
{
    public class CompanyRepository
    {
        private readonly ComeSeeThisDBEntities _entities = new ComeSeeThisDBEntities();

        #region Query Methods

        /// <summary>
        ///     Get's a (optionally filtered) list of all companies
        /// </summary>
        /// <param name="unApproved">unapproved companies: 1 - only approved, , 2 - only unapproved, 3 - include approved and unapproved</param>
        /// <param name="productType">Enum value can be All, Vehicles, Motors, Tires</param>
        /// <param name="includeAny">If set to true includes the "* Any * " company, otherwise does not include it</param>
        /// <param name="onlyCompaniesWithProducts">If set to true, it will only return companies that have a product of the specified type</param>
        /// <returns>IQueryable list of companies</returns>
        public IQueryable<Company> GetAllCompanies(int unApproved, ProductType productType, bool? includeAny = false, bool? onlyCompaniesWithProducts = false)
        {
            IOrderedQueryable<Company> result = _entities.Companies;
            var ocwp = false;
            if (onlyCompaniesWithProducts.HasValue) ocwp = (bool)onlyCompaniesWithProducts;

            // 1 - We want to show ONLY APPROVED companies
            if (unApproved == 1) result = _entities.Companies.Where(c => c.Approved).OrderBy(c => c.CompanyName);

            // 2 - We want to show only UnApproved companies
            if (unApproved == 2) result = _entities.Companies.Where(c => !c.Approved).OrderBy(c => c.CompanyName);

            // 3 - We want to show APPROVED and UnApproved companies
            if (unApproved == 3) result = _entities.Companies.OrderBy(c => c.CompanyName);

            switch (productType)
            {
                case ProductType.All:
                    break;
                case ProductType.Vehicle:
                    result = ocwp ? result.Where(mm => mm.MakesVehicles).Where(x=>x.Vehicles.Count > 0).OrderBy(c => c.CompanyName) : result.Where(mm => mm.MakesVehicles).OrderBy(c => c.CompanyName);
                    break;
                case ProductType.Motor:
                    result = ocwp ? result.Where(mm => mm.MakesMotors).Where(x => x.Motors.Count > 0).OrderBy(c => c.CompanyName) : result.Where(mm => mm.MakesMotors).OrderBy(c => c.CompanyName);
                    break;
                case ProductType.Tire:
                    result = ocwp ? result.Where(mm => mm.MakesTires).Where(x => x.Tires.Count > 0).OrderBy(c => c.CompanyName) : result.Where(mm => mm.MakesTires).OrderBy(c => c.CompanyName);
                    break;
            }

            var ia = false;
            if (includeAny.HasValue) ia = (bool)includeAny;
            return ia ? result.OrderBy(c => c.CompanyName) : result.Where(x => x.CompanyId > 1).OrderBy(x => x.CompanyName);
        }

        public Company GetCompany(int companyId)
        {
            return _entities.Companies.FirstOrDefault(c => c.CompanyId == companyId);
        }

        public List<char> GetCompanyFirstLetters(int unApproved, ProductType productType, bool? includeAny = false)
        {
            var result = GetAllCompanies(unApproved, productType, includeAny);
            return result.Select(company => company.CompanyName.Substring(0, 1).ToCharArray()[0]).ToList();
        }
        #endregion

        #region Add/Delete

        public void Add(Company company)
        {
            _entities.Companies.AddObject(company);
        }

        public void Delete(Company company)
        {
            _entities.Companies.DeleteObject(company);
        }

        #endregion

        #region Persistance

        public void Save()
        {
            _entities.SaveChanges();
        }

        #endregion
    }
}